package com.wlqq.loan.rule.config;

import com.alibaba.druid.filter.AutoLoad;
import com.alibaba.druid.filter.FilterAdapter;
import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.dianping.cat.Cat;
import com.dianping.cat.CatConstants;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;

import java.sql.SQLException;

/**
 * cat监控drui连接池
 *
 * @author flowkr90@gmail.com
 */
@AutoLoad
public class DruidCatFilter extends FilterAdapter {

    private String dbType;

    private String url;


    @Override
    public void init(DataSourceProxy dataSource) {
        dbType = dataSource.getDbType();
        url = dataSource.getUrl();
    }

    @Override
    public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        boolean result;
        try {
            result = super.statement_execute(chain, statement, sql);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }

        return result;
    }

    @Override
    public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        boolean result;
        try {
            result = super.statement_execute(chain, statement, sql, autoGeneratedKeys);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }

        return result;
    }

    @Override
    public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int[] columnIndexes)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        boolean result;
        try {
            result = super.statement_execute(chain, statement, sql, columnIndexes);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }

        return result;
    }

    @Override
    public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, String[] columnNames)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        boolean result;
        try {
            result = super.statement_execute(chain, statement, sql, columnNames);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }

        return result;
    }

    @Override
    public int[] statement_executeBatch(FilterChain chain, StatementProxy statement) throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", statement.getBatchSql());
        int[] result;
        try {
            result = super.statement_executeBatch(chain, statement);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }

        return result;
    }

    @Override
    public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        ResultSetProxy result;
        try {
            result = super.statement_executeQuery(chain, statement, sql);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }

        return result;
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        int result;
        try {
            result = super.statement_executeUpdate(chain, statement, sql);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        int result;
        try {
            result = super.statement_executeUpdate(chain, statement, sql, autoGeneratedKeys);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int[] columnIndexes)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        int result;
        try {
            result = super.statement_executeUpdate(chain, statement, sql, columnIndexes);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, String[] columnNames)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", sql);
        int result;
        try {
            result = super.statement_executeUpdate(chain, statement, sql, columnNames);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

    @Override
    public boolean preparedStatement_execute(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", statement.getSql());
        boolean result;
        try {
            result = super.preparedStatement_execute(chain, statement);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

    @Override
    public ResultSetProxy preparedStatement_executeQuery(FilterChain chain, PreparedStatementProxy statement)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", statement.getSql());
        ResultSetProxy result;
        try {
            result = super.preparedStatement_executeQuery(chain, statement);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

    @Override
    public int preparedStatement_executeUpdate(FilterChain chain, PreparedStatementProxy statement)
            throws SQLException {
        Transaction transaction = Cat.newTransaction(CatConstants.TYPE_SQL, url);
        Cat.logEvent("SQL.DbType", dbType);
        Cat.logEvent("SQL.Database", url);
        Cat.logEvent("SQL.sql", statement.getSql());
        int result;
        try {
            result = super.preparedStatement_executeUpdate(chain, statement);
            transaction.setStatus(Message.SUCCESS);
        } catch (SQLException e) {
            Cat.logError(e);
            transaction.setStatus(e);
            throw e;
        } finally {
            transaction.complete();
        }
        return result;
    }

}
